home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2008 February / PCWFEB08.iso / Software / Freeware / Miro 1.0 / Miro_Installer.exe / Miro_Downloader.exe / databaseupgrade.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2007-11-12  |  26.9 KB  |  1,073 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.5)
  3.  
  4. '''Responsible for upgrading old versions of the database.
  5.  
  6. NOTE: For really old versions (before the schema.py module, see
  7. olddatabaseupgrade.py)
  8. '''
  9. import schema
  10. import util
  11. import types
  12. from urlparse import urlparse
  13. from storedatabase import SavableObject
  14. import config
  15. import prefs
  16.  
  17. class DatabaseTooNewError(Exception):
  18.     '''Error that we raise when we see a database that is newer than the
  19.     version that we can update too.
  20.     '''
  21.     pass
  22.  
  23.  
  24. def upgrade(savedObjects, saveVersion, upgradeTo = None):
  25.     '''Upgrade a list of SavableObjects that were saved using an old version 
  26.     of the database schema.
  27.  
  28.     This method will call upgradeX for each number X between saveVersion and
  29.     upgradeTo.  For example, if saveVersion is 2 and upgradeTo is 4, this
  30.     method is equivelant to:
  31.  
  32.         upgrade3(savedObjects)
  33.         upgrade4(savedObjects)
  34.  
  35.     By default, upgradeTo will be the VERSION variable in schema.
  36.     '''
  37.     changed = set()
  38.     if upgradeTo is None:
  39.         upgradeTo = schema.VERSION
  40.     
  41.     if saveVersion > upgradeTo:
  42.         msg = 'Database was created by a newer version of Miro (db version is %s)' % saveVersion
  43.         raise DatabaseTooNewError(msg)
  44.     
  45.     while saveVersion < upgradeTo:
  46.         if util.chatter:
  47.             print 'upgrading database to version %s' % (saveVersion + 1)
  48.         
  49.         upgradeFunc = globals()['upgrade%d' % (saveVersion + 1)]
  50.         thisChanged = upgradeFunc(savedObjects)
  51.         if thisChanged is None or changed is None:
  52.             changed = None
  53.         else:
  54.             changed.update(thisChanged)
  55.         saveVersion += 1
  56.     return changed
  57.  
  58.  
  59. def upgrade2(objectList):
  60.     '''Add a dlerType variable to all RemoteDownloader objects.'''
  61.     for o in objectList:
  62.         if o.classString == 'remote-downloader':
  63.             o.savedData['status'] = { }
  64.             for key in ('startTime', 'endTime', 'filename', 'state', 'currentSize', 'totalSize', 'reasonFailed'):
  65.                 o.savedData['status'][key] = o.savedData[key]
  66.                 del o.savedData[key]
  67.             
  68.             o.savedData['dlid'] = 'noid'
  69.             continue
  70.     
  71.  
  72.  
  73. def upgrade3(objectList):
  74.     '''Add the expireTime variable to FeedImpl objects.'''
  75.     for o in objectList:
  76.         if o.classString == 'feed':
  77.             feedImpl = o.savedData['actualFeed']
  78.             if feedImpl is not None:
  79.                 feedImpl.savedData['expireTime'] = None
  80.             
  81.         feedImpl is not None
  82.     
  83.  
  84.  
  85. def upgrade4(objectList):
  86.     '''Add iconCache variables to all Item objects.'''
  87.     for o in objectList:
  88.         if o.classString in ('item', 'file-item', 'feed'):
  89.             o.savedData['iconCache'] = None
  90.             continue
  91.     
  92.  
  93.  
  94. def upgrade5(objectList):
  95.     '''Upgrade metainfo from old BitTorrent format to BitTornado format'''
  96.     for o in objectList:
  97.         if o.classString == 'remote-downloader':
  98.             if o.savedData['status'].has_key('metainfo'):
  99.                 o.savedData['status']['metainfo'] = None
  100.                 o.savedData['status']['infohash'] = None
  101.             
  102.         o.savedData['status'].has_key('metainfo')
  103.     
  104.  
  105.  
  106. def upgrade6(objectList):
  107.     '''Add downloadedTime to items.'''
  108.     for o in objectList:
  109.         if o.classString in ('item', 'file-item'):
  110.             o.savedData['downloadedTime'] = None
  111.             continue
  112.     
  113.  
  114.  
  115. def upgrade7(objectList):
  116.     '''Add the initialUpdate variable to FeedImpl objects.'''
  117.     for o in objectList:
  118.         if o.classString == 'feed':
  119.             feedImpl = o.savedData['actualFeed']
  120.             if feedImpl is not None:
  121.                 feedImpl.savedData['initialUpdate'] = False
  122.             
  123.         feedImpl is not None
  124.     
  125.  
  126.  
  127. def upgrade8(objectList):
  128.     '''Have items point to feed_id instead of feed.'''
  129.     for o in objectList:
  130.         if o.classString in ('item', 'file-item'):
  131.             o.savedData['feed_id'] = o.savedData['feed'].savedData['id']
  132.             continue
  133.     
  134.  
  135.  
  136. def upgrade9(objectList):
  137.     '''Added the deleted field to file items'''
  138.     for o in objectList:
  139.         if o.classString == 'file-item':
  140.             o.savedData['deleted'] = False
  141.             continue
  142.     
  143.  
  144.  
  145. def upgrade10(objectList):
  146.     """Add a watchedTime attribute to items.  Since we don't know when that
  147.     was, we use the downloaded time which matches with our old behaviour.
  148.     """
  149.     import datetime
  150.     changed = set()
  151.     for o in objectList:
  152.         if o.classString in ('item', 'file-item'):
  153.             if o.savedData['seen']:
  154.                 o.savedData['watchedTime'] = o.savedData['downloadedTime']
  155.             else:
  156.                 o.savedData['watchedTime'] = None
  157.             changed.add(o)
  158.             continue
  159.     
  160.     return changed
  161.  
  162.  
  163. def upgrade11(objectList):
  164.     '''We dropped the loadedThisSession field from ChannelGuide.  No need to
  165.     change anything for this.'''
  166.     return set()
  167.  
  168.  
  169. def upgrade12(objectList):
  170.     import filetypes
  171.     datetime = datetime
  172.     import datetime
  173.     changed = set()
  174.     for o in objectList:
  175.         if o.classString in ('item', 'file-item'):
  176.             if not o.savedData.has_key('releaseDateObj'):
  177.                 
  178.                 try:
  179.                     enclosures = o.savedData['entry'].enclosures
  180.                     for enc in enclosures:
  181.                         if filetypes.isVideoEnclosure(enc):
  182.                             enclosure = enc
  183.                             break
  184.                             continue
  185.                     
  186.                     o.savedData['releaseDateObj'] = datetime(*enclosure.updated_parsed[0:7])
  187.                 except:
  188.                     
  189.                     try:
  190.                         o.savedData['releaseDateObj'] = datetime(*o.savedData['entry'].updated_parsed[0:7])
  191.                     o.savedData['releaseDateObj'] = datetime.min
  192.  
  193.  
  194.                 changed.add(o)
  195.             
  196.         o.savedData.has_key('releaseDateObj')
  197.     
  198.     return changed
  199.  
  200.  
  201. def upgrade13(objectList):
  202.     '''Add an isContainerItem field.  Computing this requires reading
  203.     through files and we need to do this check anyway in onRestore, in
  204.     case it has only been half done.'''
  205.     changed = set()
  206.     todelete = []
  207.     for i in xrange(len(objectList) - 1, -1, -1):
  208.         o = objectList[i]
  209.         if o.classString in ('item', 'file-item'):
  210.             if o.savedData['feed_id'] == None:
  211.                 del objectList[i]
  212.             else:
  213.                 o.savedData['isContainerItem'] = None
  214.                 o.savedData['parent_id'] = None
  215.                 o.savedData['videoFilename'] = ''
  216.             changed.add(o)
  217.             continue
  218.     
  219.     return changed
  220.  
  221.  
  222. def upgrade14(objectList):
  223.     '''Add default and url fields to channel guide.'''
  224.     changed = set()
  225.     todelete = []
  226.     for o in objectList:
  227.         if o.classString == 'channel-guide':
  228.             o.savedData['url'] = None
  229.             changed.add(o)
  230.             continue
  231.     
  232.     return changed
  233.  
  234.  
  235. def upgrade15(objectList):
  236.     '''In the unlikely event that someone has a playlist around, change items
  237.     to item_ids.'''
  238.     changed = set()
  239.     for o in objectList:
  240.         if o.classString == 'playlist':
  241.             o.savedData['item_ids'] = o.savedData['items']
  242.             changed.add(o)
  243.             continue
  244.     
  245.     return changed
  246.  
  247.  
  248. def upgrade16(objectList):
  249.     changed = set()
  250.     for o in objectList:
  251.         if o.classString == 'file-item':
  252.             o.savedData['shortFilename'] = None
  253.             changed.add(o)
  254.             continue
  255.     
  256.     return changed
  257.  
  258.  
  259. def upgrade17(objectList):
  260.     '''Add folder_id attributes to Feed and SavedPlaylist.  Add item_ids
  261.     attribute to PlaylistFolder.
  262.     '''
  263.     changed = set()
  264.     for o in objectList:
  265.         if o.classString in ('feed', 'playlist'):
  266.             o.savedData['folder_id'] = None
  267.             changed.add(o)
  268.             continue
  269.         if o.classString == 'playlist-folder':
  270.             o.savedData['item_ids'] = []
  271.             changed.add(o)
  272.             continue
  273.     
  274.     return changed
  275.  
  276.  
  277. def upgrade18(objectList):
  278.     '''Add shortReasonFailed to RemoteDownloader status dicts. '''
  279.     changed = set()
  280.     for o in objectList:
  281.         if o.classString == 'remote-downloader':
  282.             o.savedData['status']['shortReasonFailed'] = o.savedData['status']['reasonFailed']
  283.             changed.add(o)
  284.             continue
  285.     
  286.     return changed
  287.  
  288.  
  289. def upgrade19(objectList):
  290.     '''Add origURL to RemoteDownloaders'''
  291.     changed = set()
  292.     for o in objectList:
  293.         if o.classString == 'remote-downloader':
  294.             o.savedData['origURL'] = o.savedData['url']
  295.             changed.add(o)
  296.             continue
  297.     
  298.     return changed
  299.  
  300.  
  301. def upgrade20(objectList):
  302.     '''Add redirectedURL to Guides'''
  303.     changed = set()
  304.     for o in objectList:
  305.         if o.classString == 'channel-guide':
  306.             o.savedData['redirectedURL'] = None
  307.             o.savedData['cachedGuideBody'] = None
  308.             changed.add(o)
  309.             continue
  310.     
  311.     return changed
  312.  
  313.  
  314. def upgrade21(objectList):
  315.     '''Add searchTerm to Feeds'''
  316.     changed = set()
  317.     for o in objectList:
  318.         if o.classString == 'feed':
  319.             o.savedData['searchTerm'] = None
  320.             changed.add(o)
  321.             continue
  322.     
  323.     return changed
  324.  
  325.  
  326. def upgrade22(objectList):
  327.     '''Add userTitle to Feeds'''
  328.     changed = set()
  329.     for o in objectList:
  330.         if o.classString == 'feed':
  331.             o.savedData['userTitle'] = None
  332.             changed.add(o)
  333.             continue
  334.     
  335.     return changed
  336.  
  337.  
  338. def upgrade23(objectList):
  339.     '''Remove container items from playlists.'''
  340.     changed = set()
  341.     toFilter = set()
  342.     playlists = set()
  343.     for o in objectList:
  344.         if o.classString in ('playlist', 'playlist-folder'):
  345.             playlists.add(o)
  346.             continue
  347.         if o.classString in ('item', 'file-item') and o.savedData['isContainerItem']:
  348.             toFilter.add(o.savedData['id'])
  349.             continue
  350.     
  351.     for p in playlists:
  352.         filtered = _[1]
  353.         if len(filtered) != len(p.savedData['item_ids']):
  354.             changed.add(p)
  355.             p.savedData['item_ids'] = filtered
  356.             continue
  357.         []
  358.     
  359.     return changed
  360.  
  361.  
  362. def upgrade24(objectList):
  363.     '''Upgrade metainfo back to BitTorrent format.'''
  364.     for o in objectList:
  365.         if o.classString == 'remote-downloader':
  366.             if o.savedData['status'].has_key('metainfo'):
  367.                 o.savedData['status']['metainfo'] = None
  368.                 o.savedData['status']['infohash'] = None
  369.             
  370.         o.savedData['status'].has_key('metainfo')
  371.     
  372.  
  373.  
  374. def upgrade25(objectList):
  375.     '''Remove container items from playlists.'''
  376.     datetime = datetime
  377.     import datetime
  378.     changed = set()
  379.     startfroms = { }
  380.     for o in objectList:
  381.         if o.classString == 'feed':
  382.             startfroms[o.savedData['id']] = o.savedData['actualFeed'].savedData['startfrom']
  383.             continue
  384.     
  385.     for o in objectList:
  386.         if o.classString == 'item':
  387.             pubDate = o.savedData['releaseDateObj']
  388.             feed_id = o.savedData['feed_id']
  389.             if feed_id is not None and startfroms.has_key(feed_id):
  390.                 if pubDate != datetime.max:
  391.                     pass
  392.                 o.savedData['eligibleForAutoDownload'] = pubDate >= startfroms[feed_id]
  393.             else:
  394.                 o.savedData['eligibleForAutoDownload'] = False
  395.             changed.add(o)
  396.         
  397.         if o.classString == 'file-item':
  398.             o.savedData['eligibleForAutoDownload'] = True
  399.             changed.add(o)
  400.             continue
  401.     
  402.     return changed
  403.  
  404.  
  405. def upgrade26(objectList):
  406.     changed = set()
  407.     for o in objectList:
  408.         if o.classString == 'feed':
  409.             feedImpl = o.savedData['actualFeed']
  410.             for field in ('autoDownloadable', 'getEverything', 'maxNew', 'fallBehind', 'expire', 'expireTime'):
  411.                 o.savedData[field] = feedImpl.savedData[field]
  412.             
  413.             changed.add(o)
  414.             continue
  415.     
  416.     return changed
  417.  
  418.  
  419. def upgrade27(objectList):
  420.     '''We dropped the sawIntro field from ChannelGuide.  No need to change
  421.     anything for this.'''
  422.     return set()
  423.  
  424.  
  425. def upgrade28(objectList):
  426.     import filetypes
  427.     objectList.sort(key = (lambda o: o.savedData['id']))
  428.     changed = set()
  429.     items = set()
  430.     removed = set()
  431.     
  432.     def getFirstVideoEnclosure(entry):
  433.         '''Find the first video enclosure in a feedparser entry.  Returns the
  434.         enclosure, or None if no video enclosure is found.
  435.         '''
  436.         
  437.         try:
  438.             enclosures = entry.enclosures
  439.         except (KeyError, AttributeError):
  440.             return None
  441.  
  442.         for enclosure in enclosures:
  443.             if filetypes.isVideoEnclosure(enclosure):
  444.                 return enclosure
  445.                 continue
  446.         
  447.         return None
  448.  
  449.     for i in xrange(len(objectList) - 1, -1, -1):
  450.         o = objectList[i]
  451.         if o.classString == 'item':
  452.             entry = o.savedData['entry']
  453.             videoEnc = getFirstVideoEnclosure(entry)
  454.             if videoEnc is not None:
  455.                 entryURL = videoEnc.get('url')
  456.             else:
  457.                 entryURL = None
  458.             title = entry.get('title')
  459.             feed_id = o.savedData['feed_id']
  460.             if title is not None or entryURL is not None:
  461.                 if (feed_id, entryURL, title) in items:
  462.                     removed.add(o.savedData['id'])
  463.                     changed.add(o)
  464.                     del objectList[i]
  465.                 else:
  466.                     items.add((feed_id, entryURL, title))
  467.             
  468.         entryURL is not None
  469.     
  470.     for i in xrange(len(objectList) - 1, -1, -1):
  471.         o = objectList[i]
  472.         if o.classString == 'file-item':
  473.             if o.savedData['parent_id'] in removed:
  474.                 changed.add(o)
  475.                 del objectList[i]
  476.             
  477.         o.savedData['parent_id'] in removed
  478.     
  479.     return changed
  480.  
  481.  
  482. def upgrade29(objectList):
  483.     changed = set()
  484.     for o in objectList:
  485.         if o.classString == 'guide':
  486.             o.savedData['default'] = o.savedData['url'] is None
  487.             changed.add(o)
  488.             continue
  489.     
  490.     return changed
  491.  
  492.  
  493. def upgrade30(objectList):
  494.     changed = set()
  495.     for o in objectList:
  496.         if o.classString == 'guide':
  497.             if o.savedData['default']:
  498.                 o.savedData['url'] = None
  499.                 changed.add(o)
  500.             
  501.         o.savedData['default']
  502.     
  503.     return changed
  504.  
  505.  
  506. def upgrade31(objectList):
  507.     changed = set()
  508.     for o in objectList:
  509.         if o.classString == 'remote-downloader':
  510.             o.savedData['status']['retryTime'] = None
  511.             o.savedData['status']['retryCount'] = -1
  512.             changed.add(o)
  513.             continue
  514.     
  515.     return changed
  516.  
  517.  
  518. def upgrade32(objectList):
  519.     changed = set()
  520.     for o in objectList:
  521.         if o.classString == 'remote-downloader':
  522.             o.savedData['channelName'] = None
  523.             changed.add(o)
  524.             continue
  525.     
  526.     return changed
  527.  
  528.  
  529. def upgrade33(objectList):
  530.     changed = set()
  531.     for o in objectList:
  532.         if o.classString == 'remote-downloader':
  533.             o.savedData['duration'] = None
  534.             changed.add(o)
  535.             continue
  536.     
  537.     return changed
  538.  
  539.  
  540. def upgrade34(objectList):
  541.     changed = set()
  542.     for o in objectList:
  543.         if o.classString in ('item', 'file-item'):
  544.             o.savedData['duration'] = None
  545.             changed.add(o)
  546.             continue
  547.     
  548.     return changed
  549.  
  550.  
  551. def upgrade35(objectList):
  552.     changed = set()
  553.     for o in objectList:
  554.         if o.classString in ('item', 'file-item'):
  555.             if hasattr(o.savedData, 'entry'):
  556.                 entry = o.savedData['entry']
  557.                 if entry.has_key('title') and type(entry.title) != types.UnicodeType:
  558.                     entry.title = entry.title.decode('utf-8', 'replace')
  559.                     changed.add(o)
  560.                 
  561.             
  562.         hasattr(o.savedData, 'entry')
  563.     
  564.     return changed
  565.  
  566.  
  567. def upgrade36(objectList):
  568.     changed = set()
  569.     for o in objectList:
  570.         if o.classString == 'remote-downloader':
  571.             o.savedData['manualUpload'] = False
  572.             changed.add(o)
  573.             continue
  574.     
  575.     return changed
  576.  
  577.  
  578. def upgrade37(objectList):
  579.     changed = set()
  580.     removed = set()
  581.     id = 0
  582.     for o in objectList:
  583.         if o.classString == 'feed':
  584.             feedImpl = o.savedData['actualFeed']
  585.             if feedImpl.classString == 'directory-feed-impl':
  586.                 id = o.savedData['id']
  587.                 break
  588.             
  589.         feedImpl.classString == 'directory-feed-impl'
  590.     
  591.     if id == 0:
  592.         return changed
  593.     
  594.     for i in xrange(len(objectList) - 1, -1, -1):
  595.         o = objectList[i]
  596.         if o.classString == 'file-item' and o.savedData['feed_id'] == id:
  597.             removed.add(o.savedData['id'])
  598.             changed.add(o)
  599.             del objectList[i]
  600.             continue
  601.     
  602.     for i in xrange(len(objectList) - 1, -1, -1):
  603.         o = objectList[i]
  604.         if o.classString == 'file-item':
  605.             if o.savedData['parent_id'] in removed:
  606.                 changed.add(o)
  607.                 del objectList[i]
  608.             
  609.         o.savedData['parent_id'] in removed
  610.     
  611.     return changed
  612.  
  613.  
  614. def upgrade38(objectList):
  615.     changed = set()
  616.     for o in objectList:
  617.         if o.classString == 'remote-downloader':
  618.             
  619.             try:
  620.                 if o.savedData['status']['channelName']:
  621.                     o.savedData['status']['channelName'] = o.savedData['status']['channelName'].translate({
  622.                         ord('/'): u'-',
  623.                         ord('\\'): u'-',
  624.                         ord(':'): u'-' })
  625.                     changed.add(o)
  626.  
  627.             continue
  628.     
  629.     return changed
  630.  
  631.  
  632. def upgrade39(objectList):
  633.     changed = set()
  634.     removed = set()
  635.     id = 0
  636.     for i in xrange(len(objectList) - 1, -1, -1):
  637.         o = objectList[i]
  638.         if o.classString in ('item', 'file-item'):
  639.             changed.add(o)
  640.         None if o.savedData['parent_id'] else o.classString == 'file-item'
  641.     
  642.     return changed
  643.  
  644.  
  645. def upgrade40(objectList):
  646.     changed = set()
  647.     for o in objectList:
  648.         if o.classString in ('item', 'file-item'):
  649.             o.savedData['resumeTime'] = 0
  650.             changed.add(o)
  651.             continue
  652.     
  653.     return changed
  654.  
  655.  
  656. def unicodify(d):
  657.     FeedParserDict = FeedParserDict
  658.     import feedparser
  659.     StringType = StringType
  660.     import types
  661.     if isinstance(d, FeedParserDict):
  662.         for key in d.keys():
  663.             
  664.             try:
  665.                 d[key] = unicodify(d[key])
  666.             continue
  667.             except KeyError:
  668.                 continue
  669.             
  670.  
  671.         
  672.     elif isinstance(d, dict):
  673.         for key in d.keys():
  674.             d[key] = unicodify(d[key])
  675.         
  676.     elif isinstance(d, list):
  677.         for key in range(len(d)):
  678.             d[key] = unicodify(d[key])
  679.         
  680.     elif type(d) == StringType:
  681.         d = d.decode('ascii', 'replace')
  682.     
  683.     return d
  684.  
  685.  
  686. def upgrade41(objectList):
  687.     FilenameType = FilenameType
  688.     import platformutils
  689.     if FilenameType == str:
  690.         binaryFields = [
  691.             'filename',
  692.             'videoFilename',
  693.             'shortFilename',
  694.             'offsetPath',
  695.             'initialHTML',
  696.             'status',
  697.             'channelName']
  698.         icStrings = [
  699.             'etag',
  700.             'modified',
  701.             'url']
  702.         icBinary = [
  703.             'filename']
  704.         statusBinary = [
  705.             'channelName',
  706.             'shortFilename',
  707.             'filename',
  708.             'metainfo']
  709.     else:
  710.         binaryFields = [
  711.             'initialHTML',
  712.             'status']
  713.         icStrings = [
  714.             'etag',
  715.             'modified',
  716.             'url',
  717.             'filename']
  718.         icBinary = []
  719.         statusBinary = [
  720.             'metainfo']
  721.     changed = set()
  722.     for o in objectList:
  723.         o.savedData = unicodify(o.savedData)
  724.         for field in o.savedData:
  725.             if field not in binaryFields:
  726.                 o.savedData[field] = unicodify(o.savedData[field])
  727.                 if field == 'actualFeed':
  728.                     o.savedData[field].__dict__ = unicodify(o.savedData[field].__dict__)
  729.                 elif field == 'iconCache' and o.savedData['iconCache'] is not None:
  730.                     for icfield in icStrings:
  731.                         o.savedData['iconCache'].savedData[icfield] = unicodify(o.savedData['iconCache'].savedData[icfield])
  732.                     
  733.                     for icfield in icBinary:
  734.                         if type(o.savedData['iconCache'].savedData[icfield]) == unicode:
  735.                             o.savedData['iconCache'].savedData[icfield] = o.savedData['iconCache'].savedData[icfield].encode('ascii', 'replace')
  736.                             continue
  737.                     
  738.                 
  739.             o.savedData['iconCache'] is not None
  740.             if field == 'status':
  741.                 for subfield in o.savedData['status']:
  742.                     if type(o.savedData[field][subfield]) == unicode and subfield in statusBinary:
  743.                         o.savedData[field][subfield] = o.savedData[field][subfield].encode('ascii', 'replace')
  744.                         continue
  745.                     if type(o.savedData[field][subfield]) == str and subfield not in statusBinary:
  746.                         o.savedData[field][subfield] = o.savedData[field][subfield].decode('ascii', 'replace')
  747.                         continue
  748.                 
  749.             if type(o.savedData[field]) == unicode:
  750.                 o.savedData[field] = o.savedData[field].encode('ascii', 'replace')
  751.                 continue
  752.         
  753.         if o.classString == 'channel-guide':
  754.             del o.savedData['cachedGuideBody']
  755.         
  756.         changed.add(o)
  757.     
  758.     return changed
  759.  
  760.  
  761. def upgrade42(objectList):
  762.     changed = set()
  763.     for o in objectList:
  764.         if o.classString in ('item', 'file-item'):
  765.             o.savedData['screenshot'] = None
  766.             changed.add(o)
  767.             continue
  768.     
  769.     return changed
  770.  
  771.  
  772. def upgrade43(objectList):
  773.     changed = set()
  774.     removed = set()
  775.     id = 0
  776.     for i in xrange(len(objectList) - 1, -1, -1):
  777.         o = objectList[i]
  778.         if o.classString == 'feed':
  779.             feedImpl = o.savedData['actualFeed']
  780.             if feedImpl.classString == 'manual-feed-impl':
  781.                 id = o.savedData['id']
  782.                 break
  783.             
  784.         feedImpl.classString == 'manual-feed-impl'
  785.     
  786.     for i in xrange(len(objectList) - 1, -1, -1):
  787.         o = objectList[i]
  788.         if o.classString == 'file-item' and o.savedData['feed_id'] == id and o.savedData['deleted'] == True:
  789.             removed.add(o.savedData['id'])
  790.             changed.add(o)
  791.             del objectList[i]
  792.             continue
  793.     
  794.     for i in xrange(len(objectList) - 1, -1, -1):
  795.         o = objectList[i]
  796.         if o.classString == 'file-item':
  797.             if o.savedData['parent_id'] in removed:
  798.                 changed.add(o)
  799.                 del objectList[i]
  800.             
  801.         o.savedData['parent_id'] in removed
  802.     
  803.     return changed
  804.  
  805.  
  806. def upgrade44(objectList):
  807.     changed = set()
  808.     for o in objectList:
  809.         if 'iconCache' in o.savedData and o.savedData['iconCache'] is not None:
  810.             iconCache = o.savedData['iconCache']
  811.             iconCache.savedData['resized_filenames'] = { }
  812.             changed.add(o)
  813.             continue
  814.     
  815.     return changed
  816.  
  817.  
  818. def upgrade45(objectList):
  819.     '''Dropped the ChannelGuide.redirected URL attribute.  Just need to bump
  820.     the db version number.'''
  821.     return set()
  822.  
  823.  
  824. def upgrade46(objectList):
  825.     '''fastResumeData should be str, not unicode.'''
  826.     changed = set()
  827.     for o in objectList:
  828.         if o.classString == 'remote-downloader':
  829.             
  830.             try:
  831.                 if type(o.savedData['status']['fastResumeData']) == unicode:
  832.                     o.savedData['status']['fastResumeData'] = o.savedData['status']['fastResumeData'].encode('ascii', 'replace')
  833.                 
  834.                 changed.add(o)
  835.  
  836.             continue
  837.     
  838.     return changed
  839.  
  840.  
  841. def upgrade47(objectList):
  842.     '''Parsed item entries must be unicode'''
  843.     changed = set()
  844.     for o in objectList:
  845.         if o.classString == 'item':
  846.             o.savedData['entry'] = unicodify(o.savedData['entry'])
  847.             changed.add(o)
  848.             continue
  849.     
  850.     return changed
  851.  
  852.  
  853. def upgrade48(objectList):
  854.     changed = set()
  855.     removed = set()
  856.     ids = set()
  857.     for o in objectList:
  858.         if o.classString == 'feed':
  859.             feedImpl = o.savedData['actualFeed']
  860.             if feedImpl.classString == 'directory-watch-feed-impl':
  861.                 ids.add(o.savedData['id'])
  862.             
  863.         feedImpl.classString == 'directory-watch-feed-impl'
  864.     
  865.     if len(ids) == 0:
  866.         return changed
  867.     
  868.     for i in xrange(len(objectList) - 1, -1, -1):
  869.         o = objectList[i]
  870.         if o.classString == 'file-item' and o.savedData['feed_id'] in ids:
  871.             removed.add(o.savedData['id'])
  872.             changed.add(o)
  873.             del objectList[i]
  874.             continue
  875.     
  876.     for i in xrange(len(objectList) - 1, -1, -1):
  877.         o = objectList[i]
  878.         if o.classString == 'file-item':
  879.             if o.savedData['parent_id'] in removed:
  880.                 changed.add(o)
  881.                 del objectList[i]
  882.             
  883.         o.savedData['parent_id'] in removed
  884.     
  885.     return changed
  886.  
  887. upgrade49 = upgrade42
  888.  
  889. def upgrade50(objectList):
  890.     '''Parsed item entries must be unicode'''
  891.     changed = set()
  892.     for o in objectList:
  893.         if o.classString in ('item', 'file-item'):
  894.             if o.savedData['videoFilename'] and o.savedData['videoFilename'][0] == '\\':
  895.                 o.savedData['videoFilename'] = o.savedData['videoFilename'][1:]
  896.                 changed.add(o)
  897.             
  898.         o.savedData['videoFilename'][0] == '\\'
  899.     
  900.     return changed
  901.  
  902.  
  903. def upgrade51(objectList):
  904.     '''Added title field to channel guides'''
  905.     changed = set()
  906.     for o in objectList:
  907.         if o.classString in 'channel-guide':
  908.             o.savedData['title'] = None
  909.             changed.add(o)
  910.             continue
  911.     
  912.     return changed
  913.  
  914.  
  915. def upgrade52(objectList):
  916.     import filetypes
  917.     changed = set()
  918.     removed = set()
  919.     search_id = 0
  920.     downloads_id = 0
  921.     
  922.     def getVideoInfo(o):
  923.         '''Find the first video enclosure in a feedparser entry.  Returns the
  924.         enclosure, or None if no video enclosure is found.
  925.         '''
  926.         entry = o.savedData['entry']
  927.         enc = None
  928.         
  929.         try:
  930.             enclosures = entry.enclosures
  931.         except (KeyError, AttributeError):
  932.             pass
  933.  
  934.         for enclosure in enclosures:
  935.             if filetypes.isVideoEnclosure(enclosure):
  936.                 enc = enclosure
  937.                 continue
  938.         
  939.         if enc is not None:
  940.             url = enc.get('url')
  941.         else:
  942.             url = None
  943.         id = entry.get('id')
  944.         id = entry.get('guid', id)
  945.         title = entry.get('title')
  946.         return (url, id, title)
  947.  
  948.     for o in objectList:
  949.         if o.classString == 'feed':
  950.             feedImpl = o.savedData['actualFeed']
  951.             if feedImpl.classString == 'search-feed-impl':
  952.                 search_id = o.savedData['id']
  953.             elif feedImpl.classString == 'search-downloads-feed-impl':
  954.                 downloads_id = o.savedData['id']
  955.             
  956.         feedImpl.classString == 'search-feed-impl'
  957.     
  958.     items_by_idURL = { }
  959.     items_by_titleURL = { }
  960.     if search_id != 0:
  961.         for o in objectList:
  962.             if o.classString == 'item':
  963.                 if o.savedData['feed_id'] == search_id:
  964.                     (url, id, title) = getVideoInfo(o)
  965.                     if url and id:
  966.                         items_by_idURL[(id, url)] = o
  967.                     
  968.                     if url and title:
  969.                         items_by_titleURL[(title, url)] = o
  970.                     
  971.                 
  972.             o.savedData['feed_id'] == search_id
  973.         
  974.     
  975.     if downloads_id != 0:
  976.         for i in xrange(len(objectList) - 1, -1, -1):
  977.             o = objectList[i]
  978.             if o.classString == 'item':
  979.                 if o.savedData['feed_id'] == downloads_id:
  980.                     remove = False
  981.                     (url, id, title) = getVideoInfo(o)
  982.                     if url and id:
  983.                         if items_by_idURL.has_key((id, url)):
  984.                             remove = True
  985.                         else:
  986.                             items_by_idURL[(id, url)] = o
  987.                     
  988.                     if url and title:
  989.                         if items_by_titleURL.has_key((title, url)):
  990.                             remove = True
  991.                         else:
  992.                             items_by_titleURL[(title, url)] = o
  993.                     
  994.                     if remove:
  995.                         removed.add(o.savedData['id'])
  996.                         changed.add(o)
  997.                         del objectList[i]
  998.                     
  999.                 
  1000.             o.savedData['feed_id'] == downloads_id
  1001.         
  1002.         for i in xrange(len(objectList) - 1, -1, -1):
  1003.             o = objectList[i]
  1004.             if o.classString == 'file-item':
  1005.                 if o.savedData['parent_id'] in removed:
  1006.                     changed.add(o)
  1007.                     del objectList[i]
  1008.                 
  1009.             o.savedData['parent_id'] in removed
  1010.         
  1011.     
  1012.     return changed
  1013.  
  1014.  
  1015. def upgrade53(objectList):
  1016.     '''Added favicon and icon cache field to channel guides'''
  1017.     changed = set()
  1018.     for o in objectList:
  1019.         if o.classString in 'channel-guide':
  1020.             o.savedData['favicon'] = None
  1021.             o.savedData['iconCache'] = None
  1022.             o.savedData['updated_url'] = o.savedData['url']
  1023.             changed.add(o)
  1024.             continue
  1025.     
  1026.     return changed
  1027.  
  1028.  
  1029. def upgrade54(objectList):
  1030.     changed = set()
  1031.     if config.get(prefs.APP_PLATFORM) != 'windows-xul':
  1032.         return changed
  1033.     
  1034.     for o in objectList:
  1035.         if o.classString in ('item', 'file-item'):
  1036.             o.savedData['screenshot'] = None
  1037.             o.savedData['duration'] = None
  1038.             changed.add(o)
  1039.             continue
  1040.     
  1041.     return changed
  1042.  
  1043.  
  1044. def upgrade55(objectList):
  1045.     '''Add resized_screenshots attribute. '''
  1046.     changed = set()
  1047.     for o in objectList:
  1048.         if o.classString in ('item', 'file-item'):
  1049.             o.savedData['resized_screenshots'] = { }
  1050.             changed.add(o)
  1051.             continue
  1052.     
  1053.     return changed
  1054.  
  1055.  
  1056. def upgrade56(objectList):
  1057.     '''Added firstTime field to channel guides'''
  1058.     changed = set()
  1059.     for o in objectList:
  1060.         if o.classString in 'channel-guide':
  1061.             o.savedData['firstTime'] = False
  1062.             changed.add(o)
  1063.             continue
  1064.     
  1065.     return changed
  1066.  
  1067.  
  1068. def upgrade57(objectList):
  1069.     '''Added ThemeHistory'''
  1070.     changed = set()
  1071.     return changed
  1072.  
  1073.